Descripción del proyecto!¶
La finalidad del proyecto es identificar si patrones para determinar el éxito de un juego, o en su defecto, el fracaso en ventas de otros; para la tienda Ice que vende videojuegos por todo el mundo.
Base de datos del proyecto: games.csv. Contiene datos de ventas de video juegos desde el año 1980 hasta 2016.
1. Importe de librerias y estudio de datos suministrados¶
import pandas as pd
import plotly.graph_objects as go
from scipy.stats import ttest_ind
df_video_games = pd.read_csv('./datasets/games.csv') # Lectura de los datos
df_video_games.sample(10) # Encabezados e información de los datos
| Name | Platform | Year_of_Release | Genre | NA_sales | EU_sales | JP_sales | Other_sales | Critic_Score | User_Score | Rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 15666 | Tantei Opera: Milky Holmes | PSP | 2010.0 | Adventure | 0.00 | 0.00 | 0.02 | 0.00 | NaN | NaN | NaN |
| 7977 | Phantasy Star Online Ver. 2 | DC | 2001.0 | Role-Playing | 0.00 | 0.00 | 0.19 | 0.00 | 80.0 | 8.9 | T |
| 8628 | Solitaire Overload Plus | DS | 2010.0 | Misc | 0.15 | 0.00 | 0.00 | 0.01 | NaN | tbd | E |
| 430 | Enter the Matrix | PS2 | 2003.0 | Action | 1.78 | 1.12 | 0.09 | 0.19 | 62.0 | 8.1 | T |
| 3015 | Red Steel | Wii | 2006.0 | Shooter | 0.54 | 0.03 | 0.04 | 0.05 | 63.0 | 6.8 | T |
| 3520 | Rapala: We Fish | Wii | 2009.0 | Sports | 0.52 | 0.01 | 0.00 | 0.04 | NaN | tbd | E |
| 5721 | J Stars Victory Vs. | PS3 | 2014.0 | Fighting | 0.05 | 0.05 | 0.20 | 0.02 | NaN | 7.9 | NaN |
| 16227 | Monster Rancher Advance 2 | GBA | 2002.0 | Simulation | 0.01 | 0.00 | 0.00 | 0.00 | 79.0 | 9.4 | E |
| 11484 | Space Channel 5 Special Edition | PS2 | 2003.0 | Misc | 0.04 | 0.03 | 0.00 | 0.01 | 79.0 | 8.6 | T |
| 2624 | Marvel vs. Capcom: Clash of Super Heroes | PS | 1999.0 | Fighting | 0.43 | 0.30 | 0.00 | 0.05 | NaN | NaN | NaN |
df_video_games.info() # Información relevante para la reparación de los datos
<class 'pandas.core.frame.DataFrame'> RangeIndex: 16715 entries, 0 to 16714 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Name 16713 non-null object 1 Platform 16715 non-null object 2 Year_of_Release 16446 non-null float64 3 Genre 16713 non-null object 4 NA_sales 16715 non-null float64 5 EU_sales 16715 non-null float64 6 JP_sales 16715 non-null float64 7 Other_sales 16715 non-null float64 8 Critic_Score 8137 non-null float64 9 User_Score 10014 non-null object 10 Rating 9949 non-null object dtypes: float64(6), object(5) memory usage: 1.4+ MB
2. Preparación de los datos¶
Una vez observados los datos, se hará el Procesamiento de Datos de la siguiente manera:
- Pasar los nombre de columnas a minúsculas.
- Cambiar el tipo de dato para las columnas
year_of_releaseporint, ya que no tendremos mayor análisis con esta fecha, yuser_scoreporfloat, ya que se trata de una puntuación. - Tratamiento de datos nulos, los cuales se completarán mediante API request para completar al máximo datos ausente, ya que son representativos para las columnas
critic_score, user_score, yrating, con un 51%, 54% y 40% de datos faltantes respectivamente. - Limpieza los datos para la columna
user_score, que contiene datosTBDsignifica "to be determined", los cuales se considerarán como Nan. - Verificación de duplicados
# Nombre de columnas en minúscula
df_video_games.columns = df_video_games.columns.str.lower()
# Conversión de tipo de dato a int conservando los Nan
df_video_games['year_of_release'] = df_video_games['year_of_release'].astype(pd.Int64Dtype())
# valores TBD se manejan como nan, y la columna queda con tipo de dato float
df_video_games['user_score'] = pd.to_numeric(df_video_games['user_score'], errors='coerce')
# Conversión de los datos a minúnculas y verificación de duplicados
df_video_games = df_video_games.apply(lambda x: x.str.lower() if x.dtype == '0' else x)
df_video_games.duplicated().sum()
0
(df_video_games.isna().sum()/df_video_games.shape[0])*100 # Porcentaje de valores ausentes
name 0.011965 platform 0.000000 year_of_release 1.609333 genre 0.011965 na_sales 0.000000 eu_sales 0.000000 jp_sales 0.000000 other_sales 0.000000 critic_score 51.319174 user_score 54.591684 rating 40.478612 dtype: float64
Los datos nulos de las columnas name y genre coinciden, por tanto se eliminan del new_new_new_dataFrame
df_video_games.dropna(subset=['name', 'genre'], inplace=True)
df_video_games.isna().sum()/df_video_games.shape[0]
name 0.000000 platform 0.000000 year_of_release 0.016095 genre 0.000000 na_sales 0.000000 eu_sales 0.000000 jp_sales 0.000000 other_sales 0.000000 critic_score 0.513133 user_score 0.545863 rating 0.404715 dtype: float64
3. Análisis Exploratorio¶
3.1 Cantidad de juegos lanzados durante los años 1980 hasta 2016.¶
- ¿Son significativos los datos de cada período?
# Opción con pivot_table
""" games_by_year = df_video_games.pivot_table(index='year_of_release', values='name', aggfunc='count')
games_by_year.columns = ['amount_of_games']
games_by_year.reset_index(inplace=True) """
# Opción groupby y pivot_table
graph_bar = df_video_games.groupby('year_of_release')['name'].count().reset_index().rename(columns={'name': 'amount_of_games'})
fig_0 = go.Figure()
fig_0.add_trace(go.Bar(
x=graph_bar['year_of_release'],
y=graph_bar['amount_of_games'],
marker=dict(
color=graph_bar['year_of_release'], # Use a numeric array for color scale
colorscale='Viridis', # Set the colorscale
colorbar=dict(title='Amount of Games') # Add colorbar with title
)
))
fig_0.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
#width=700,
#height=700,
title='Amount of games releases by Year',
xaxis_title='Year',
yaxis_title='Amount'
)
fig_0.show(renderer='notebook')
3.2 Ventas por plataforma¶
df_video_games['total_sales_in_millions_usd'] = df_video_games[['na_sales', 'eu_sales', 'jp_sales', 'other_sales']].sum(axis=1) # Agregando columna con el total de ventas
# Reordenando el orden de las columnas
column_order = [
'name', 'platform', 'year_of_release', 'genre', 'na_sales', 'eu_sales',
'jp_sales', 'other_sales', 'total_sales_in_millions_usd', 'critic_score', 'user_score', 'rating'
]
df_video_games = df_video_games[column_order]
# Verificación de juegos que no tuvieron ventas / Eliminación de dos juegos sin ventas
(df_video_games.loc[df_video_games['total_sales_in_millions_usd'] == 0]).dropna()
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | total_sales_in_millions_usd | critic_score | user_score | rating |
|---|
# Las 10 plataformas con más ventas durante un periodo
sales_by_platform = (
df_video_games.groupby(['platform', 'year_of_release'])['total_sales_in_millions_usd']
.sum()
.reset_index()
.sort_values('total_sales_in_millions_usd', ignore_index=True)
.tail(10)
.sort_values('year_of_release', ignore_index=True)
.reset_index(drop=True)
)
sales_by_platform
| platform | year_of_release | total_sales_in_millions_usd | |
|---|---|---|---|
| 0 | PS | 1998 | 169.49 |
| 1 | PS2 | 2001 | 166.43 |
| 2 | PS2 | 2002 | 205.38 |
| 3 | PS2 | 2003 | 184.31 |
| 4 | PS2 | 2004 | 211.81 |
| 5 | PS2 | 2005 | 160.66 |
| 6 | Wii | 2008 | 171.32 |
| 7 | Wii | 2009 | 206.97 |
| 8 | X360 | 2010 | 170.03 |
| 9 | PS3 | 2011 | 156.78 |
# Las 10 plataformas con más ventas durante el periodo de 1980 a 2016
top10_sales_by_platform = (
df_video_games.groupby('platform',)['total_sales_in_millions_usd']
.sum()
.reset_index(name='total_sales_in_millions_usd')
.sort_values('total_sales_in_millions_usd', ignore_index=True, ascending=False)
.head(10)
)
top10_sales_by_platform
| platform | total_sales_in_millions_usd | |
|---|---|---|
| 0 | PS2 | 1255.77 |
| 1 | X360 | 971.42 |
| 2 | PS3 | 939.65 |
| 3 | Wii | 907.51 |
| 4 | DS | 806.12 |
| 5 | PS | 730.86 |
| 6 | GBA | 317.85 |
| 7 | PS4 | 314.14 |
| 8 | PSP | 294.05 |
| 9 | PC | 259.52 |
top_10 = list(top10_sales_by_platform['platform'])
fig = go.Figure()
data = {}
for item in top_10:
data[item] = df_video_games[df_video_games['platform'] == item][['year_of_release', 'total_sales_in_millions_usd']].groupby('year_of_release')['total_sales_in_millions_usd'].sum().reset_index()
def sales_graphic(data, figure):
color_counter = 9
colors = [
'rgba(0, 48, 73, 0.7)',
'rgba(54, 46, 65, 0.7)',
'rgba(107, 44, 57, 0.7)',
'rgba(161, 42, 49, 0.7)',
'rgba(214, 40, 40, 0.7)',
'rgba(231, 84, 20, 0.7)',
'rgba(247, 127, 0, 0.7)',
'rgba(250, 159, 37, 0.7)',
'rgba(143, 95, 3, 0.7)',
'rgba(196, 149, 57, 0.7)'
]
line_colors = [
'rgba(0, 48, 73, 1)',
'rgba(54, 46, 65, 1)',
'rgba(107, 44, 57, 1)',
'rgba(161, 42, 49, 1)',
'rgba(214, 40, 40, 1)',
'rgba(231, 84, 20, 1)',
'rgba(247, 127, 0, 1)',
'rgba(250, 159, 37, 1)',
'rgba(143, 95, 3, 1)',
'rgba(196, 149, 57, 1)'
]
for item, filter_data in data.items():
figure.add_trace(go.Bar(
x=filter_data['year_of_release'],
y=filter_data['total_sales_in_millions_usd'],
name=item,
marker=dict(
color=colors[color_counter],
line=dict(color=line_colors[color_counter])
)
))
color_counter -= 1
""" print()
print(filter_data) """
return figure.update_layout(barmode='stack', bargap=0.1, plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',)
sales_graphic(data, fig)
Analizandas las gráficas de los videojuegos con mayores ventas durante el periodo comprendido entre 1980 y 2016, se llega a la conclusión de que, en promedio, las plataformas muestran una distribución normal de ventas a lo largo de 5 años. En base a esto, se evidencia que las plataformas PS, PSP, PS2, DS, WII y GBA experimentaron éxito durante un período al rededor de 5 años, pero en la actualidad han perdido popularidad.
3.3 Analisis de las ventas apartir de la vigencia 2002.¶
- Se descartarán dos de las plataformas, PS2 y WII, que en su momento tuvieron un gran éxito en ventas. No obstante, serán irrelevantes para considerarlas en los siguientes análisis, ya que quedaron obsoletas.
- Se ejecutará un gráfico para analizar las ventas por plataforma, de las 4 que al 2016 aún mantenían una presencia significativa en el mercado.
# Nuevo DataFrame con ventas a partir del 2002.
df_since2002_video_games = df_video_games.loc[df_video_games['year_of_release'] > 2012]
top_4 = ['X360', 'PC', 'PS3', 'PS4']
fig2 = go.Figure()
new_data = {item: df_since2002_video_games[df_since2002_video_games['platform'] == item][['year_of_release', 'total_sales_in_millions_usd']].groupby('year_of_release')['total_sales_in_millions_usd'].sum().reset_index() for item in top_4}
sales_graphic(new_data,fig2)
Vemos como la plataforma X360 que contaba como un crecimiento significativo desde 2006, se ha venido viendo afectada por las ventas de PS4, que por ser una consola más reciente en el mercada, va remarcando en las ventas, y se espera que sus ventas sigan apuntando para 2017; mejor aun, se podría estar evaluando que nuevas plataformas están a punto de salir al mercado.
3.4 Diagrama de cajas¶
- Determinar si son significativas las diferencias en las ventas y,
- Qué sucede con las ventas promedio en las plataformas
fig3 = go.Figure()
color_counter = 0
colors = [
'rgba(0, 48, 73, 0.7)',
'rgba(54, 46, 65, 0.7)',
'rgba(107, 44, 57, 0.7)',
'rgba(161, 42, 49, 0.7)',
'rgba(214, 40, 40, 0.7)',
'rgba(231, 84, 20, 0.7)',
'rgba(247, 127, 0, 0.7)',
'rgba(250, 159, 37, 0.7)',
'rgba(143, 95, 3, 0.7)',
'rgba(196, 149, 57, 0.7)'
]
line_colors = [
'rgba(0, 48, 73, 1)',
'rgba(54, 46, 65, 1)',
'rgba(107, 44, 57, 1)',
'rgba(161, 42, 49, 1)',
'rgba(214, 40, 40, 1)',
'rgba(231, 84, 20, 1)',
'rgba(247, 127, 0, 1)',
'rgba(250, 159, 37, 1)',
'rgba(143, 95, 3, 1)',
'rgba(196, 149, 57, 1)'
]
for item, filter_data in new_data.items():
fig3.add_trace(go.Box(
y=filter_data['total_sales_in_millions_usd'],
name=item,
marker=dict(
color=colors[color_counter],
line=dict(
color=line_colors[color_counter]
)
)
))
color_counter += 1
fig3.update_layout( plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',)
fig3.show(renderer='notebook')
El gráfico de cajas destaca la variabilidad en las ventas de las cuatro plataformas. Se observa que, en los últimos cuatro años, PS4 lidera en ventas, con un promedio superior a las dos plataformas siguientes, PS3 y X360. En contraste, las ventas de PC, aunque han experimentado un crecimiento constante desde 2004, se sitúan considerablemente por debajo del promedio de las otras plataformas. Por lo tanto, para el modelo de 2017, no se considera como una opción competitiva en términos de ventas, en comparación con las otras plataformas mencionadas.
Posterior a este analisis, se hara evalución del valor atípico que refleja la plataforma PC
sales_pc_platform = new_data['PC']
# Calcular el rango intercuartílico (IQR)
q1 = sales_pc_platform['total_sales_in_millions_usd'].quantile(0.25)
q3 = sales_pc_platform['total_sales_in_millions_usd'].quantile(0.75)
iqr = q3 -q1
# Identifica los valores atípicos
outliers = sales_pc_platform[(sales_pc_platform['total_sales_in_millions_usd'] < q1 - 1.5 * iqr) | (sales_pc_platform['total_sales_in_millions_usd'] > q3 + 1.5 * iqr)]
outliers
| year_of_release | total_sales_in_millions_usd |
|---|
3.5 Gráfico de dispersión¶
- Que muentre la correlación entre las reseñas y las ventas.
critic_score_data = df_since2002_video_games.loc[~df_since2002_video_games['critic_score'].isna()][['total_sales_in_millions_usd', 'critic_score']]
# Crear el gráfico de dispersión
fig4 = go.Figure()
fig4.add_trace(go.Scatter(
x=critic_score_data['critic_score'],
y=critic_score_data['total_sales_in_millions_usd'],
mode='markers',
marker=dict(
size=5,
color=critic_score_data['critic_score'], # Utilizar colores según la variable critic_score
colorscale='Viridis', # Cambiar la escala de colores
colorbar=dict(title='Critic Score') # Agregar una barra de colores
)
))
# Configurar el diseño del gráfico
fig4.update_layout(
title='Gráfico de Dispersión: Critic Score vs Ventas',
xaxis=dict(title='Critic Score'),
yaxis=dict(title='Ventas in Millones USD'),
showlegend=False, # Desactivar la leyenda para este ejemplo
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)'
)
# Calcular la correlación
correlation = critic_score_data['critic_score'].corr(critic_score_data['total_sales_in_millions_usd'])
print(f'Correlación entre Critic Score y ventas: {correlation}')
# Mostrar el gráfico
fig4.show(renderer='notebook')
Correlación entre Critic Score y ventas: 0.3136995151027369
Analizando la gráfica, se podría concluir que existe una correlación entre critic_score y total_sales_in_millions_usd, indicando que en la medida de que las criticas sean positivas, las ventas aunmentan; sin embargo, el coeficiente de correlación de 0.3136 indica que aunque existe una relación positiva, esta relación se considera débil, ya que es bastante cerca a 0.
critic_score_by_game = df_since2002_video_games.loc[~df_since2002_video_games['critic_score'].isna()][['name', 'platform', 'total_sales_in_millions_usd']]
critic_score_by_game.pivot_table(
index='name',
columns='platform',
values='total_sales_in_millions_usd',
aggfunc='sum',
margins=True,
margins_name='Total'
).fillna(0.00)
| platform | 3DS | PC | PS3 | PS4 | PSP | PSV | WiiU | X360 | XOne | Total |
|---|---|---|---|---|---|---|---|---|---|---|
| name | ||||||||||
| 2014 FIFA World Cup Brazil | 0.00 | 0.00 | 0.61 | 0.00 | 0.00 | 0.00 | 0.00 | 0.43 | 0.00 | 1.04 |
| 7 Days to Die | 0.00 | 0.00 | 0.00 | 0.14 | 0.00 | 0.00 | 0.00 | 0.00 | 0.05 | 0.19 |
| 7th Dragon III Code: VFD | 0.16 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.16 |
| A-Train: City Simulator | 0.06 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.06 |
| Act of Aggression | 0.00 | 0.01 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.01 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| Zombie Army Trilogy | 0.00 | 0.00 | 0.00 | 0.20 | 0.00 | 0.00 | 0.00 | 0.00 | 0.11 | 0.31 |
| Zumba Fitness: World Party | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.24 | 0.24 |
| htoL#NiQ: The Firefly Diary | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 0.01 | 0.00 | 0.00 | 0.00 | 0.01 |
| inFAMOUS: Second Son | 0.00 | 0.00 | 0.00 | 2.79 | 0.00 | 0.00 | 0.00 | 0.00 | 0.00 | 2.79 |
| Total | 40.32 | 34.84 | 114.07 | 244.49 | 0.15 | 13.99 | 51.42 | 85.27 | 130.40 | 714.95 |
559 rows × 10 columns
#Distribución general de los juegos por género
game_by_genre = df_since2002_video_games.loc[~((df_since2002_video_games['critic_score'].isna()) | (df_since2002_video_games['rating'].isna()))][['name', 'total_sales_in_millions_usd', 'rating']]
game_by_genre.pivot_table(
index='name',
columns='rating',
values='total_sales_in_millions_usd',
aggfunc='sum',
margins=True,
margins_name='total'
).fillna(0.00).sort_values('total').tail(20)
| rating | E | E10+ | M | T | total |
|---|---|---|---|---|---|
| name | |||||
| Far Cry 4 | 0.00 | 0.00 | 6.31 | 0.00 | 6.31 |
| Tom Clancy's The Division | 0.00 | 0.00 | 6.38 | 0.00 | 6.38 |
| Battlefield 1 | 0.00 | 0.00 | 6.70 | 0.00 | 6.70 |
| NBA 2K14 | 6.97 | 0.00 | 0.00 | 0.00 | 6.97 |
| Call of Duty: Infinite Warfare | 0.00 | 0.00 | 7.02 | 0.00 | 7.02 |
| Mario Kart 8 | 7.09 | 0.00 | 0.00 | 0.00 | 7.09 |
| LEGO Marvel Super Heroes | 0.00 | 7.47 | 0.00 | 0.00 | 7.47 |
| Assassin's Creed: Unity | 0.00 | 0.00 | 8.01 | 0.00 | 8.01 |
| FIFA 15 | 8.55 | 0.00 | 0.00 | 0.00 | 8.55 |
| Destiny | 0.00 | 0.00 | 0.00 | 9.01 | 9.01 |
| FIFA 17 | 10.37 | 0.00 | 0.00 | 0.00 | 10.37 |
| Assassin's Creed IV: Black Flag | 0.00 | 0.00 | 10.82 | 0.00 | 10.82 |
| FIFA 16 | 12.03 | 0.00 | 0.00 | 0.00 | 12.03 |
| Fallout 4 | 0.00 | 0.00 | 12.67 | 0.00 | 12.67 |
| Call of Duty: Advanced Warfare | 0.00 | 0.00 | 13.33 | 0.00 | 13.33 |
| Battlefield 4 | 0.00 | 0.00 | 13.94 | 0.00 | 13.94 |
| FIFA 14 | 15.25 | 0.00 | 0.00 | 0.00 | 15.25 |
| Call of Duty: Ghosts | 0.00 | 0.00 | 26.70 | 0.00 | 26.70 |
| Grand Theft Auto V | 0.00 | 0.00 | 56.58 | 0.00 | 56.58 |
| total | 167.84 | 84.46 | 345.05 | 113.65 | 711.00 |
# distribución por género
game_by_genre = df_since2002_video_games.loc[~((df_since2002_video_games['critic_score'].isna()) | (df_since2002_video_games['rating'].isna()))][['name', 'year_of_release', 'total_sales_in_millions_usd', 'rating']]
game_by_genre.pivot_table(
index='rating',
columns='year_of_release',
values='total_sales_in_millions_usd',
aggfunc='sum',
).sort_index()
| year_of_release | 2013 | 2014 | 2015 | 2016 |
|---|---|---|---|---|
| rating | ||||
| E | 63.46 | 40.88 | 39.73 | 23.77 |
| E10+ | 34.27 | 20.89 | 22.00 | 7.30 |
| M | 142.74 | 93.75 | 70.37 | 38.19 |
| T | 26.82 | 37.15 | 27.08 | 22.60 |
Las ventas por género son de gran importancia a la hora de elaborar un modelo, ya que son de gran relevancia las categorias T, M y E.
4. Análisis por Región¶
# Ventas en Norteamérica
na_data_frame = df_since2002_video_games.drop(['eu_sales', 'jp_sales', 'other_sales', 'total_sales_in_millions_usd'], axis=1)\
.loc[df_since2002_video_games['na_sales'] != 0.00]
na = na_data_frame.groupby('platform')['na_sales'].agg(['count', 'sum']).reset_index().sort_values('sum').tail()
na.rename(columns={'count': 'na_sales_count', 'sum': 'na_sales_sum'}, inplace=True)
na['unit_price'] = na['na_sales_count'] / na['na_sales_sum']
na
| platform | na_sales_count | na_sales_sum | unit_price | |
|---|---|---|---|---|
| 0 | 3DS | 119 | 38.20 | 3.115183 |
| 3 | PS3 | 211 | 63.50 | 3.322835 |
| 8 | X360 | 170 | 81.66 | 2.081803 |
| 9 | XOne | 227 | 93.12 | 2.437715 |
| 4 | PS4 | 294 | 108.74 | 2.703697 |
# Ventas en Europa
eu_data_frame = df_since2002_video_games.drop(['na_sales', 'jp_sales', 'other_sales', 'total_sales_in_millions_usd'], axis=1)\
.loc[df_since2002_video_games['eu_sales'] != 0.00]
eu = eu_data_frame.groupby('platform')['eu_sales'].agg(['count', 'sum']).reset_index().sort_values('sum').tail()
eu.sort_values('platform', inplace=True)
eu['unit_price'] = eu['count'] / eu['sum']
eu
| platform | count | sum | unit_price | |
|---|---|---|---|---|
| 0 | 3DS | 122 | 30.96 | 3.940568 |
| 3 | PS3 | 212 | 67.81 | 3.126383 |
| 4 | PS4 | 290 | 141.09 | 2.055426 |
| 9 | X360 | 169 | 42.52 | 3.974600 |
| 10 | XOne | 218 | 51.59 | 4.225625 |
# Ventas en Japón
jp_data_frame = df_since2002_video_games.drop(['na_sales', 'eu_sales', 'other_sales', 'total_sales_in_millions_usd'], axis=1)\
.loc[df_since2002_video_games['jp_sales'] != 0.00]
jp = jp_data_frame.groupby('platform')['jp_sales'].agg(['count', 'sum']).reset_index().sort_values('sum').tail()
jp.sort_values('platform', inplace=True)
jp['unit_price'] = jp['count'] / jp['sum']
jp
#jp_data_frame.loc[jp_data_frame['jp_sales'] == 0.01]
| platform | count | sum | unit_price | |
|---|---|---|---|---|
| 0 | 3DS | 235 | 67.81 | 3.465566 |
| 1 | PS3 | 236 | 23.35 | 10.107066 |
| 2 | PS4 | 223 | 15.96 | 13.972431 |
| 4 | PSV | 316 | 18.59 | 16.998386 |
| 6 | WiiU | 57 | 10.88 | 5.238971 |
Podemos identificar que las 3 plataformas en común con mayores ventas en estas paises son: DS, PS2 y PS3; pero que el precio final por consumidor varia significativamente, dependiente de la región. Como ejemplo podemos ver como el precio para PS3 en NA y EU está al rededor de 2.70 USD, mientras que en JP cuatriplica este valor.
4.1 Los cinco géneros principales¶
# Los cinco géneros principales para Norteamérica y Europa
na_data_by_genre = na_data_frame.groupby('platform')['na_sales'].agg(['count', 'sum']).reset_index().sort_values('sum').tail()
top5_genre = (na_data_by_genre.merge(na_data_frame[['platform', 'genre']], on='platform')
).groupby('genre')['platform'].count().reset_index().sort_values('platform').tail()
#Graficar
fig5 = go.Figure()
count_color_fig5 = 0
fig5.add_trace(go.Bar(
x=top5_genre['genre'],
y=top5_genre['platform'],
marker=dict(
color='rgba(107, 44, 57, 0.7)',
line=dict(
color='rgba(250, 159, 37, 1)'
)
)
))
fig5.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
title='Most popular video game genres in North America and Europe',
xaxis_title='Genre',
yaxis_title='Number of scores'
)
fig5.show(renderer='notebook')
# Los cinco géneros principales para Japón
jp_data_by_genre = jp_data_frame.groupby('platform')['jp_sales'].agg(['count', 'sum']).reset_index().sort_values('sum').tail()
top5_genre_jp = (jp_data_by_genre.merge(jp_data_frame[['platform', 'genre']], on='platform')
).groupby('genre')['platform'].count().reset_index().sort_values('platform').tail()
#Graficar resultado del top 5 de generos más comunes
fig6 = go.Figure()
count_color_fig6 = 0
fig6.add_trace(go.Bar(
x=top5_genre_jp['genre'],
y=top5_genre_jp['platform'],
marker=dict(
color='rgba(107, 44, 57, 0.7)',
line=dict(
color='rgba(250, 159, 37, 1)'
)
)
))
fig6.update_layout(
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
title='Most popular video game genres',
xaxis_title='Genre',
yaxis_title='Number of scores'
)
fig6.show(renderer='notebook')
Se concluye que los 5 generos principales son [Action, Msic, Sports, Shooter, Racing], ya que son populares tando para Norteamérica, como en Europa. En Japón se a diferencia de los dos ultimos, cuentas con gran popularidad Adventure y Role-Playing.
4.2 Clasificaciones de ESRB vs ventas por regiones¶
regions = ['na_sales', 'eu_sales', 'jp_sales']
df_data_by_esrb = df_since2002_video_games[df_since2002_video_games['rating'].notna()].reset_index(drop=True)
rating_by_esrb = df_data_by_esrb.groupby('rating')[regions].sum().reset_index()
#Graficas ventas por regíon
fig7 = go.Figure()
count_color_fig7 = 0
for region in regions:
# Add traces for each region
fig7.add_trace(go.Bar(
x=rating_by_esrb['rating'],
y=rating_by_esrb[region],
name=region,
marker=dict(
color=colors[count_color_fig7],
line=dict(
color=line_colors[count_color_fig7]
)
)
))
count_color_fig7 +=1
fig7.update_layout(
barmode='group', # Use 'group' for grouped bars
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)',
title='Total Sales by ESRB Rating and Region',
xaxis_title='ESRB Rating',
yaxis_title='Total Sales'
)
fig7.show(renderer='notebook')
Podemos evidenciar que las clasificaciones para todos(E) y mayores de 17(M), son las categorias que más cuentas con ventas, estonces será otro criterio a consideración para el modelo 2017.
5. Prueba de hipótesis estadísticas¶
- Las calificaciones promedio de los usuarios para las plataformas Xbox One y PC son las mismas.
- Las calificaciones promedio de los usuarios para los géneros de Acción y Deportes son diferentes.
# Prueba las hipótesis:
# Ho: No hay diferencia entre las calificaciones promedio de los usuarios para las plataformas XOne y PC.
# H¡: Hay diferencia entre las calificaciones promedio de los usuarios para las plataformas XOne y PC.
# Realizar prueba t de Student con un α = 0.01.
x_one_score = df_since2002_video_games.query("platform == 'XOne' and user_score.notna()")['user_score'].reset_index(drop=True)
pc_score = df_since2002_video_games.query("platform == 'PC' and user_score.notna()")['user_score'].reset_index(drop=True)
# establece un nivel crítico de significación estadística:
alpha = 0.01
# Probar la hipótesis de que no hay diferencia entre las calificaciones promedio de los usuarios para las plataformas XOne y PC.
result = ttest_ind(x_one_score, pc_score)
print('valor p:', result.pvalue)
# Comparar el valor P obtenido con el nivel de significación estadística:
if result.pvalue < alpha:
print("Rechazamos la hipótesis nula")
else:
print("No podemos rechazar la hipótesis nula")
valor p: 0.14012658403611647 No podemos rechazar la hipótesis nula
No hay información estadística suficiente para afirmar que los promedios de las calificaciones de los usuarios para las plataformas XOne y PC son iguales.
# Prueba las hipótesis:
# Ho: Hay diferencia entre las calificaciones promedio de los usuarios para los géneros de Acción y Deportes.
# H¡: No hay diferencia entre las calificaciones promedio de los usuarios para los géneros de Acción y Deportes.
# Realizar prueba t de Student con un α = 0.01.
action_score = df_since2002_video_games.query("genre == 'Action' and user_score.notna()")['user_score'].reset_index(drop=True)
sport_score = df_since2002_video_games.query("genre == 'Sports' and user_score.notna()")['user_score'].reset_index(drop=True)
# establece un nivel crítico de significación estadística:
alpha = 0.01
# Probar la hipótesis de que no hay diferencia entre las calificaciones promedio de los usuarios para las plataformas XOne y PC.
result = ttest_ind(action_score, sport_score)
print('valor p:', result.pvalue)
# Comparar el valor P obtenido con el nivel de significación estadística:
if result.pvalue < alpha:
print("Rechazamos la hipótesis nula")
else:
print("No podemos rechazar la hipótesis nula")
valor p: 1.0517832389140023e-27 Rechazamos la hipótesis nula
Se realizó prueba t de Student, donde se asume que los tados tienden a terner distribución normal, y se aplicó ttes_ind, ya que se intenta comparar las medias de dos DataFrames.
Conclusión general¶
En base a los datos analizados, se llega a concluir que la evolución de los videojuegos ha desempeñado un papel crucial en el mercado, dado el notable impacto en la audiencia y, por consiguiente, en las ventas generadas por las diversas plataformas que los promocionan.
Es posible inferir que los datos son significativos en cada periodo, ya que reflejan un ritmo constante de crecimiento. A partir de 1994, este crecimiento experimentó una aceleración, posiblemente atribuible a la transición hacia sistemas de 16 bits en esa época. Hacia mediados de 1999, la introducción de la primera consola doméstica habilitada para Internet marcó un hito, sugiriendo que el crecimiento en las ventas se disparó gracias a los continuos avances tecnológicos.
Las ventas alcanzaron su punto máximo durante los periodos comprendidos entre 2006 y 2011, posterior a estas fechas, se observa una tendencia decreciente, que hasta ahora se desconocen los motivos. También es relevante destacar que las plataformas tienen una vida útil aproximada de alrededor de cinco años, como claramente se evidencia en las gráficas de ventas por plataforma.
En resumen, la evolución de los videojuegos no solo ha marcado hitos significativos en términos de ventas y tecnología, sino que también ha delineado ciclos de vida para las plataformas, influyendo en las tendencias y preferencias de los consumidores. Estos datos proporcionan una visión integral de la dinámica cambiante de la industria de los videojuegos a lo largo del tiempo, y lo que se tendrá en cuenta para el modelo 2017.
NOTA: No se realizó tratamiento a los datos nulos, por tanto se realizaron los análisis sin considerar datos faltante